package com.orm.base.proxy;


import com.orm.base.DefaultMyMapperImpl;
import lombok.AllArgsConstructor;

import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

@AllArgsConstructor
public class MyMapperProxy implements InvocationHandler {

    // 目标接口 userMapper.class
    private Class mapperInterface;


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        if (method.isDefault()) {
            // 调用 default 方法
            return MethodHandles.lookup()
                    .findSpecial(
                            method.getDeclaringClass(),
                            method.getName(),
                            MethodType.methodType(method.getReturnType(), method.getParameterTypes()),
                            method.getDeclaringClass())
                    .bindTo(proxy)
                    .invokeWithArguments(args);
        } else {
            // 代理其他方法
            DefaultMyMapperImpl defaultMyMapper = new DefaultMyMapperImpl(mapperInterface);
            defaultMyMapper.setInterfaceClass(mapperInterface);
            return method.invoke(defaultMyMapper, args);
        }

    }


    @SuppressWarnings("unchecked")
    public static <T> T createProxy(Class<T> mapperInterface) {
        return (T) Proxy.newProxyInstance(
                mapperInterface.getClassLoader(),
                new Class[]{mapperInterface},
                new MyMapperProxy(mapperInterface)
        );
    }
}
